"""
Case Type   : 系统内部使用工具
Case Name   : 同一主机build该主机相同同端口级联备
Create At   : 2022/06/08
Owner       : opentestcase012
Description :
    1.备1节点初始化数据库
    1.备1节点配置guc参数
    3.级联备配置guc参数
    4.build相同端口级联备
    5.清理环境
Expect      :
    1.数据库初始化成功
    2.guc参数配置成功
    3.guc参数配置成功
    4.build失败
    5.环境清理成功
History     :
"""
import os
import unittest

from yat.test import Node
from yat.test import macro

from testcase.utils.Common import Common
from testcase.utils.Common import CommonSH
from testcase.utils.Logger import Logger

primary_sh = CommonSH('PrimaryDbUser')


@unittest.skipIf(3 != primary_sh.get_node_num(), '非1+2环境不执行')
class Tools(unittest.TestCase):
    def setUp(self):
        self.log = Logger()
        self.common = Common()
        self.log.info(f'----{os.path.basename(__file__)} start----')
        self.primary_node = Node('PrimaryDbUser')
        self.standby1_root_node = Node('Standby1Root')
        self.standby1_node = Node('Standby1DbUser')
        self.standby2_root_node = Node('Standby2Root')
        self.standby2_node = Node('Standby2DbUser')
        self.pri_host = self.primary_node.ssh_host
        self.sta1_host = self.standby1_node.ssh_host
        self.port = self.standby1_node.db_port
        self.dn_path = os.path.join(os.path.dirname(macro.DB_INSTANCE_PATH),
                                    'dn_path')
        self.conf_path = os.path.join(macro.DB_INSTANCE_PATH,
                                      macro.DB_PG_CONFIG_NAME)

    def test_gs_ctl(self):
        text = '----step1:在备1执行init数据库 expect:成功----'
        self.log.info(text)
        mkdir_cmd = f'rm -rf {self.dn_path};' \
                    f'mkdir {self.dn_path};ls {os.path.dirname(self.dn_path)}'
        self.log.info(mkdir_cmd)
        dir_res = self.common.get_sh_result(self.standby1_node, mkdir_cmd)
        self.assertIn('dn_path', dir_res, '文件夹创建失败')

        init_cmd = f'source {macro.DB_ENV_PATH};' \
                   f'gs_initdb {self.dn_path} -w"{macro.COMMON_PASSWD}" ' \
                   f'--nodename=single'
        self.log.info(init_cmd)
        init_res = self.common.get_sh_result(self.standby1_node, init_cmd)
        self.assertIn('Success', init_res, 'init失败')

        text = '----step2:在备1配置guc参数 expect:成功----'
        self.log.info(text)
        text = '----查看主机名----'
        self.log.info(text)
        global sta1_nodename
        sta1_nodename = self.common.get_sh_result(self.standby1_root_node,
                                                  "uname -n")
        self.assertIsNotNone(sta1_nodename, '执行失败:' + text)

        local_port = int(self.port) + 1
        localheartbeatport = int(self.port) + 5
        localservice = int(self.port) + 4
        guc_cmd = f'source {macro.DB_ENV_PATH};' \
                  f'gs_guc reload -D {macro.DB_INSTANCE_PATH} ' \
                  f'-N {sta1_nodename} -c ' \
                  f'"replconninfo3 = \'localhost={self.sta1_host} ' \
                  f'localport={local_port} ' \
                  f'localheartbeatport={localheartbeatport} ' \
                  f'localservice={localservice} ' \
                  f'remotehost={self.sta1_host} ' \
                  f'remoteport={local_port} ' \
                  f'remoteheartbeatport={localheartbeatport} ' \
                  f'remoteservice={localservice}\'"'
        self.log.info(guc_cmd)
        guc_res = self.common.get_sh_result(self.standby1_node, guc_cmd)
        self.assertIn('Success to perform gs_guc', guc_res, 'guc设置失败')

        text = '----step3:在级联备配置guc参数 expect:成功----'
        self.log.info(text)
        az_cmd = f'cat {self.conf_path} | grep AZ'
        self.log.info(az_cmd)
        available_zone = self.common.get_sh_result(self.standby1_node,
                                                   az_cmd).split('\'')[-2]
        guc_cmd1 = f'source {macro.DB_ENV_PATH};' \
                   f'gs_guc set -D {self.dn_path} ' \
                   f'-N {sta1_nodename} -c ' \
                   f'"replconninfo1 = \'localhost={self.sta1_host} ' \
                   f'localport={local_port} ' \
                   f'localheartbeatport={localheartbeatport} ' \
                   f'localservice={localservice} ' \
                   f'remotehost={self.sta1_host} ' \
                   f'remoteport={local_port} ' \
                   f'remoteheartbeatport={localheartbeatport} ' \
                   f'remoteservice={localservice}\'"'
        self.log.info(guc_cmd1)
        guc_res1 = self.common.get_sh_result(self.standby1_node, guc_cmd1)
        self.assertIn('Success to perform gs_guc', guc_res1, 'guc设置失败')

        guc_cmd2 = f'source {macro.DB_ENV_PATH};' \
                   f'gs_guc set -D {self.dn_path} -c ' \
                   f'"listen_addresses=\'localhost,{self.sta1_host}\'"'
        self.log.info(guc_cmd2)
        guc_res2 = self.common.get_sh_result(self.standby1_node, guc_cmd2)
        self.assertIn('Success to perform gs_guc', guc_res2, 'guc设置失败')

        guc_cmd3 = f'source {macro.DB_ENV_PATH};' \
                   f'gs_guc set -D {self.dn_path} -c ' \
                   f'"port=\'{self.port}\'"'
        self.log.info(guc_cmd3)
        guc_res3 = self.common.get_sh_result(self.standby1_node, guc_cmd3)
        self.assertIn('Success to perform gs_guc', guc_res3, 'guc设置失败')

        guc_cmd4 = f'source {macro.DB_ENV_PATH};' \
                   f'gs_guc set -D {self.dn_path} -c ' \
                   f'"local_bind_address=\'{self.sta1_host}\'"'
        self.log.info(guc_cmd4)
        guc_res4 = self.common.get_sh_result(self.standby1_node, guc_cmd4)
        self.assertIn('Success to perform gs_guc', guc_res4, 'guc设置失败')

        guc_cmd5 = f'source {macro.DB_ENV_PATH};' \
                   f'gs_guc set -D {self.dn_path} -c ' \
                   f'"available_zone=\'{available_zone}\'"'
        self.log.info(guc_cmd5)
        guc_res5 = self.common.get_sh_result(self.standby1_node, guc_cmd5)
        self.assertIn('Success to perform gs_guc', guc_res5, 'guc设置失败')

        text = '----step4:build级联备 expect:失败----'
        self.log.info(text)
        build_cmd = f'source {macro.DB_ENV_PATH};' \
                    f'gs_ctl build -b standby_full -D {self.dn_path} ' \
                    f'-C "localhost={self.sta1_host} localport={self.port} ' \
                    f'remotehost={self.sta1_host}  remoteport={self.port}" ' \
                    f'-M casecade_standby'
        self.log.info(build_cmd)
        build_res = self.common.get_sh_result(self.standby1_node, build_cmd)
        check_res = f'FATAL:  could not create ' \
                    f'listen socket for "localhost:{self.port}"'
        self.assertIn(check_res, build_res, '备机build失败')

    def tearDown(self):
        text = "----step5:恢复环境 expect:成功----"
        self.log.info(text)
        del_cmd = f'rm -rf {self.dn_path};ls {os.path.dirname(self.dn_path)}'
        self.log.info(del_cmd)
        del_res = self.common.get_sh_result(self.standby1_root_node, del_cmd)
        guc_cmd = f'source {macro.DB_ENV_PATH};' \
                  f'gs_guc set -D {macro.DB_INSTANCE_PATH} ' \
                  f'-N {sta1_nodename} -c ' \
                  f'"replconninfo3 = \'\'"'
        self.log.info(guc_cmd)
        guc_res = self.common.get_sh_result(self.standby1_node, guc_cmd)
        restart_cmd = f'source {macro.DB_ENV_PATH};' \
                      f'gs_ctl restart -D {macro.DB_INSTANCE_PATH}'
        self.log.info(restart_cmd)
        restart_res = self.common.get_sh_result(self.primary_node, restart_cmd)
        self.assertNotIn('dn_path', del_res, '文件删除失败')
        self.assertIn('Success to perform gs_guc', guc_res, 'guc设置失败')
        self.assertIn('server started', restart_res, '数据库重启失败')
        self.log.info(f'----{os.path.basename(__file__)} finish----')
